
#import "NntpPanelControl.h"
#import "ServerCell.h"
#import "MainWindowControl.h"
#import "NNTP.h"
#import "ArticleSet.h"
#import "NewsgroupSet.h"
#import "KillFilePanel.subproj/KillPanelController.h"
#import "descriptors.h"
#import "ArticleViewControl.h"
#include "regexpr.h"
#import "Alexandra.h"
#import "Composer.h"

@implementation NntpPanelControl

void handler(DPSTimedEntry te,double now, char *userData)
{
	[((id)userData) newNewsAllServer:(id)userData];
}

- appWillTerminate:sender
{
   int i,j;
	id result=self;
	
	result=[Composer confirmTermination];
	if(result){
   	for(i=0,j=[nrList count];i<j;i++)
      	[[nrList objectAt:i] free];
	}	
  
	return result;
}


- appDidBecomeActive:sender;
	{
	if([NXApp defaultBoolValue:DEFAULT_CHECKNN_ACTIVATION]){
		[self renewNewNewsTimedEntry:self];
		[self newNewsAllServer:self];
	}
		//[NXApp sendAction:@selector(newNews:) to:nil from:self];
		
	return self;
	}
	

- app:sender powerOffIn:(int)ms andSave:(BOOL)save
{
   int i,j;

   for(i=0,j=[nrList count];i<j;i++)
      [[nrList objectAt:i] free];
  
	return self;
}

- setupMenu:menu;
	{
	id		aCell,aMenu;
	int		n,i;
	
	aMenu=[[menu itemList] cellList];
	n=[aMenu count];
	for(i=0;i<n;i++)
		{
    	aCell=[aMenu objectAt:i];
      	if(![aCell isEnabled])
			{
	        [aCell setEnabled:TRUE];
	     	if([aCell hasSubmenu])
				[self setupMenu:[aCell target]];
			else
				{
				[aCell setUpdateAction:@selector(menuActive:) forMenu:menu];
				}
         	}
      	}
	return self;
   	}
	


- appDidInit:sender
{
   const char *buf;
   BOOL openServers;
   NXSize newCellSize,cellDist;
   NXRect frameRect;
   ServerCell *aCell;

   openServers=FALSE;

   nrList=[[List alloc] init];
   [serverNameMatrix getFrame:&frameRect];
   newCellSize.height=16.0;
   newCellSize.width = frameRect.size.width;
   cellDist.width=0.0;
   cellDist.height=0.0;

   [[serverNameMatrix superview] setAutoresizeSubviews:YES];
   [serverNameMatrix setAutosizing:NX_WIDTHSIZABLE];
   [serverNameMatrix setAutosizeCells:YES];
   [serverNameMatrix setIntercell:&cellDist];
   [[serverNameMatrix setCellSize:&newCellSize] setMode:NX_RADIOMODE];
   [serverNameMatrix setMode:NX_RADIOMODE];
   [serverNameMatrix setEmptySelectionEnabled:YES];
   [serverNameMatrix setDoubleAction:[openButton action]];
 
   aCell=[[ServerCell alloc] init];
   [[[aCell setSlowLink:FALSE] setOpenOnStartup:FALSE] serverClosed:self];
   [serverNameMatrix setPrototype:aCell];

   [self setupMenu:mainMenu];
   [NXApp setAutoupdate:TRUE];

   //insert servernames in matrix
   if(((buf=[NXApp defaultValue:"NNTPServer"])!=NULL)&&(*buf!='\0')){
      List *cellList;
      int i,j;

      if(buf[0]=='\0')
         return self;
      [self addCellsToMatrix:buf];
      cellList=[serverNameMatrix cellList];
      j=[cellList count];
      for(i=0;i<j;i++){
         id aCell=[cellList objectAt:i];
         [aCell readServerOptions];
         if([aCell openOnStartup]==TRUE){
            [serverNameMatrix selectCellAt:i:0];
            [self openServer:self];
            openServers=TRUE;
         }
      }
      if(openServers==TRUE){
         [serverNameMatrix selectCellAt:-1:-1];
      }
   }
   if(openServers==FALSE)
      [[serverNameMatrix window] makeKeyAndOrderFront:self];

   //which regular expression syntax to use?
   buf=[NXApp defaultValue:"RegExprSyntax"];
   if(buf!=NULL){
      if(!strcasecmp(buf,"EMACS"))
         re_set_syntax(RE_SYNTAX_EMACS);
      if(!strcasecmp(buf,"AWK"))
         re_set_syntax(RE_SYNTAX_AWK);
      else if(!strcasecmp(buf,"EGREP"))
         re_set_syntax(RE_SYNTAX_EGREP);
      else if(!strcasecmp(buf,"GREP"))
         re_set_syntax(RE_SYNTAX_GREP);
   }

	[ERROR_MANAGER addObserver:self 
						selector:@selector(renewNewNewsTimedEntry:)
						forError:ENOTEPrefsChanged];
						
	[self renewNewNewsTimedEntry:self];
	
	[[NXApp appListener] setServicesDelegate:self];
	 
   return self;
} 

- addCellsToMatrix:(const char *)serverlist
{
   char buf[200];
   const char *ptr;
   int r,c;
   id aCell;

   ptr=serverlist;
   while((ptr!=NULL)&&(ptr[0]!='\0')){
      sscanf(ptr,"%s",buf);
      [serverNameMatrix getNumRows:&r numCols:&c];
      [serverNameMatrix addRow];
      aCell=[serverNameMatrix cellAt:r :0];
      [aCell setStringValue:buf];

      ptr+=strlen(buf);
      if(ptr[0]==' ')
         ptr++;
   }
   [serverNameMatrix sizeToCells];
    
   return self;
}

- addNewServer:sender
{
   int i;
   int r,c;
   ServerCell *aCell;
   const char *aString;

   aString=[newServerName stringValue];
	if(strchr(aString,' ')){
		NXRunAlertPanel("ALEXANDRA","No space characters allowed in the nntp server name.",NULL,NULL,NULL);
		return self;
	}
   if(aString[0]!='\0'){
      [serverNameMatrix getNumRows:&r numCols:&c];
      for(i=0;i<r;i++)
         if(strcmp([[serverNameMatrix cellAt:i :0] stringValue],aString)==0)
            return self;
      [self addCellsToMatrix:aString];
      aCell=[serverNameMatrix cellAt:r :0];
      [aCell setOpenOnStartup:([newServerOOS state]==1)];
      [aCell setSlowLink:([newServerSL state]==1)];
		[aCell setUserString:[newServerUser stringValue] ];
      [aCell setPasswdString:[newServerPassword stringValue] ];
      [serverNameMatrix display];
      [self addServerToDefaultDB:aString];
      [aCell writeServerOptions];
   }
   [[newServerName controlView] selectTextAt:0];
   return self;
}

- serverWillClose:sender
{
   int i,j;
   List *cellList;
   const char *servername=[[sender nntpServer] serverName];

   cellList=[serverNameMatrix cellList];
   j=[cellList count];
   for(i=0;i<j;i++){
      ServerCell *aCell=[cellList objectAt:i];
      if(strcmp([aCell stringValue],servername)==0){
         [aCell serverClosed:self];
         break;
      }
   }
   [nrList removeObject:sender];
   [serverNameMatrix display];

   return self;
}

- openServer:sender
{
   int i,j;

   [serverNameMatrix getNumRows:&j numCols:&i];
   for(i=0;i<j;i++){
      ServerCell *aCell=[serverNameMatrix cellAt:i :0];
      if(([aCell state]==1)&&([aCell isOpen]==FALSE)){
         //open server
         if(starter==nil)
            if([NXApp loadNibSection:"newsreader.nib" owner:self withNames:NO]==nil)
               return nil;
         if([starter connectNNTP:[aCell stringValue] slowLink:[aCell slowLink]]==TRUE){
            [nrList addObject:starter];
            [aCell serverOpened:self];
            starter=nil;
         }
      }
   }
   [serverNameMatrix display];
   return self;
}

- removeServer:sender
{
   int i,j;

	[serverNameMatrix getNumRows:&j numCols:&i];
   for(i=j-1;i>=0;i--){
      ServerCell *aCell=[serverNameMatrix cellAt:i :0];
      if(([aCell state]==1)&&([aCell isOpen]==FALSE)){
         [self removeServerFromDefaultDB:[aCell stringValue]];
         [serverNameMatrix removeRowAt:i andFree:YES];
      }
   }
   [[serverNameMatrix sizeToCells] display];
   [self serverSelected:self];
   return self;
}

- serverSelected:sender
{
   List *selList;
   int j;
   
   selList=[serverNameMatrix getSelectedCells:nil];
   j=[selList count];
   if(j==1){
      ServerCell *aCell=[selList objectAt:0];
      [[newServerOOS setState:(int)[aCell openOnStartup]] display];
      [[newServerSL setState:(int)[aCell slowLink]] display];
		[newServerUser setStringValue:[aCell user]];
		[newServerPassword setStringValue:[aCell pass]];
      [newServerName takeStringValueFrom:[selList lastObject]];
      [[newServerName controlView] selectTextAt:0];
      [openButton setEnabled:![aCell isOpen]];
		[removeButton setEnabled:![aCell isOpen]]; 
   }
   else {
      [[newServerOOS setState:0] display];
      [[newServerSL setState:0] display];
      [newServerName setStringValue:""];
		[newServerPassword setStringValue:""];
		[newServerUser setStringValue:""];
      [openButton setEnabled:FALSE];
		[removeButton setEnabled:FALSE];
   }
      
   [selList free];
   return self;
}


- windowDidUpdate:(Window *)sender;
	{
	const char	*uname;
	int			i,r,c;
	
	if([NXApp keyWindow]!=[serverNameMatrix window])
		return self;

	uname=[newServerName stringValue];
	[serverNameMatrix getNumRows:&r numCols:&c];
	for(i=0;i<r;i++)
		if(!strcmp([[serverNameMatrix cellAt:i:0] stringValue],uname))
			break;
	if(i==r){
		[serverNameMatrix selectCellAt:-1:-1];
		[openButton setEnabled:FALSE];
		[removeButton setEnabled:FALSE];
		//[newServerUser setStringValue:""];
		//[newServerPassword setStringValue:""];
   }
	else{
		ServerCell *aCell=[serverNameMatrix cellAt:i:0];
		[serverNameMatrix selectCellAt:i:0];
      [openButton setEnabled:![aCell isOpen]];
		[removeButton setEnabled:![aCell isOpen]];
		//[newServerUser setStringValue:[aCell user]];
		//[newServerPassword setStringValue:[aCell pass]];
   }

	[addButton setEnabled:((i==r)&&(uname[0]!='\0'))];

	return self;
	}
		

- openOnStartup:sender
{
   id selCell=[serverNameMatrix selectedCell];

   if(selCell!=nil){
      [selCell setOpenOnStartup:(BOOL)[newServerOOS state]];
      [selCell writeServerOptions];
   }
   return self;
}

- slowLink:sender
{
  id selCell=[serverNameMatrix selectedCell];

   if(selCell!=nil){
      [selCell setSlowLink:(BOOL)[newServerSL state]];
      [selCell writeServerOptions];
   }
   return self;
}

- (BOOL)menuActive:menuCell
{
   id currentDelegate=[[NXApp mainWindow] delegate];
   BOOL askIfEnable=[currentDelegate isKindOf:[MainWindowControl class]];
   BOOL menuEnabled=[menuCell isEnabled];
   BOOL enable;

   if(askIfEnable==TRUE){
      const char *menuTitle=[menuCell title];
      const char *action=[actionTable valueForStringKey:menuTitle];
      if(action!=NULL){
         if(strcmp(action,"sorting")==0)
            enable=[currentDelegate sortCellEnabled:menuCell];
         else if(strcmp(action,"viewselector")==0)
            enable=[currentDelegate selectViewCellEnabled:menuCell];
         else if(strcmp(action,"headerfield")==0)
            enable=[currentDelegate headermodeCellEnabled:menuCell];
         else{
            SEL aSel=sel_getUid(action);
            int e=(int)[currentDelegate perform:aSel];
            enable=(e==1);
            if(enable&&([menuCell action]==@selector(killAuthor:)))
               enable=[currentDelegate killAuthorEnabled];
         }
      }
      else
         enable=TRUE;
   }
   else
      enable=FALSE;

   if(enable!=menuEnabled){
      [menuCell setEnabled:enable];
      return TRUE;
   }
   return FALSE;
}

- addServerToDefaultDB:(const char *)name
{
   char *buf;
   const char *server=[NXApp defaultValue:"NNTPServer"];
   
   if((server==NULL)||(server[0]=='\0')){
      [NXApp setDefault:"NNTPServer" to:name];
      return self;
   }
   buf=(char *)malloc((strlen(name)+strlen(server)+2)*sizeof(char));
   strcpy(buf,server);
   if(server!=NULL)
      strcat(buf," ");
   strcat(buf,name);
   
   [NXApp setDefault:"NNTPServer" to:buf];
   free(buf);

   return self;
}

- removeServerFromDefaultDB:(const char *)name
{
   int i;
   char *buf;
   char *tail;
   const char *server=[NXApp defaultValue:"NNTPServer"];

   tail=strstr(server,name);
   if(tail!=NULL){
      i=strlen(server)-strlen(tail);
      buf=(char *)malloc(strlen(server)*sizeof(char));
      tail+=strlen(name);
      if(tail[0]==' ')
         tail++;
      else if(i>0)
         i--;
      strncpy(buf,server,i);
      buf[i]='\0';
      strcat(buf,tail);
      [NXApp setDefault:"NNTPServer" to:buf];
      free(buf);
   }
   
   return self;
}

- showKillPanel:sender
{
   if(![[[NXApp mainWindow] delegate] isKindOf:[MainWindowControl class]])
      return self;

   if(killPanelController==nil)
      if([NXApp loadNibSection:"KillPanel.nib" owner:self withNames:NO]==nil){
         killPanelController=nil;
         return nil;
      }
   [killPanelController showPanel:[NXApp mainWindow]];
   return self;
}

- showArticleInspector:sender
{
	static id articleInspector=nil;
	
	if(!articleInspector)
		articleInspector=[[ArticleHeaderController alloc] init];
		
	[[articleInspector window] makeKeyAndOrderFront:self];
		
	return self;
}

- setUser:sender
{
   id selCell=[serverNameMatrix selectedCell];

   if(selCell!=nil){
      [selCell setUserString:[newServerUser stringValue]];
      [selCell writeServerOptions];
   }
   return self;
}

- setPasswd:sender
{
   id selCell=[serverNameMatrix selectedCell];

   if(selCell!=nil){
      [selCell setPasswdString:[newServerPassword stringValue]];
      [selCell writeServerOptions];
   }
   return self;
}

- newNewsAllServer:sender
{
	int i,j=[nrList count];
	
	for(i=0;i<j;i++)
		[[[nrList objectAt:i] newsgroupSet] newNews:self];

	return self;
}

- renewNewNewsTimedEntry:sender
{
	int interval;
	
	[self removeNewNewsTimedEntry:self];
		
	interval=[NXApp defaultIntValue:DEFAULT_CHECKNN_PERIOD];
	if(interval>0)
		newNewsTE=DPSAddTimedEntry(interval*60.0,(DPSTimedEntryProc)handler,
											self,NX_BASETHRESHOLD);
	
	return self;
}

- removeNewNewsTimedEntry:sender
{
	if(newNewsTE){
		DPSRemoveTimedEntry(newNewsTE);
		newNewsTE=0;
	}
	
	return self;
}

- performURLService:pboard userData:(const char *)data error:(char **)err
{
	char *buf,*url;
	int length,i,j;
	
	[pboard types];
	[pboard readType:NXAsciiPboardType data:&buf length:&length];
	
	if(length>5){
		id aCell=nil;
		
		url=malloc((length+2)*sizeof(char));
		strncpy(url,buf,length);
		url[length]='\0';
		
		[serverNameMatrix getNumRows:&j numCols:&i];
		for(i=0;i<j;i++){
			id someCell=[serverNameMatrix cellAt:i :0];
			if([someCell isOpen]){
				aCell=someCell;
				break;
			}
		}
		
		if(aCell){
			id mc=nil;
			for(i=0,j=[nrList count];i<j;i++){
				id aMainController=[nrList objectAt:i];
				if(!strcmp([[aMainController nntpServer] serverName],
								[aCell stringValue])){
					mc=aMainController;
					break;
				}
			}
			[[mc newsgroupSet] selectURL:url];
		}
		else
			NXRunAlertPanel("Service","Can't select article. No connection to any server.",NULL,NULL,NULL);
			
		free(url);
	}
	else
		NXRunAlertPanel("Service","No valid URL.",NULL,NULL,NULL);
		
	[pboard deallocatePasteboardData:buf length:length];

	return self;
}
	
@end
